/*************************************************************************
 * @file: undoredo.h
 * @date: 01/04/2012
 * TOPOL v1_0 - (c)copyright 2012 TEC/UFF
 *************************************************************************
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 ************************************************************************/

#ifndef _UNDOREDO
#define _UNDOREDO

// includes
//----------
#include <stack>

// forward declarations
//----------------------
class EulerOperator;


/*!
 * CLASS
 * UndoRedo
 * 
 * This class is responsible for manage the undo and redo operations of
 * commands executed in the Data Structure. It still considers multi-level
 * undo and redo operations. For management, it takes in account two stacks
 * one to store the undo operations and other to store the redo operations.
 * In addition, it is based on the Command Design Pattern.
 * 
 * @author Andre Pereira (andremaues@id.uff.br)
 * @version 1.0.0
 * @see EulerOperator
 */
class UndoRedo
{

public:

  ////////////////////////////////////////////////
  ///  Constructor and Destructor Declaration  ///
  ////////////////////////////////////////////////

  /**
   * @brief Constructs the object responsible to manage the undo and redo
   *        operations in the Data Structure
   */
  UndoRedo();

  ////////////////////////////////////
  ///  PUBLIC Methods Declaration  ///
  ////////////////////////////////////

  /**
   * @brief Checks if it is possible to perform an undo of a command
   * @return bool indicates the permission to perform an undo operation
   */
  bool hasUndo();

  /**
   * @brief Checks if it is possible to perform a redo of a command
   * @return bool indicates the permission to perform a redo operation
   */
  bool hasRedo();

  /**
   * @brief Inserts a new command that can be undone and/or redone
   * @param _command indicates the command to be undone or redone
   */
  void insertCommand( EulerOperator* _command );

  /**
   * @brief Performs undo operations
   * @param _levels is the number of undo operations that will be done
   */
  void undo( int _levels = 1 );

  /**
   * @brief Performs redo operations
   * @param _levels is the number of redo operations that will be done
   */
  void redo( int _levels = 1 );


private:

  ////////////////////////////////
  ///  Attributes Declaration  ///
  ////////////////////////////////

  /** @brief Stack to stores the commands that can be undone */
  std::stack<EulerOperator*> m_undocommands;

  /** @brief Stack to stores the commands that can be redone */
  std::stack<EulerOperator*> m_redocommands;

};

#endif
